package exogwt.server.web;

import org.exoplatform.container.SessionContainer;
import org.exoplatform.container.client.ClientInfo;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.*;
import java.io.IOException;

import exogwt.server.util.Exo;
import exogwt.server.ServiceClientInfo;

/**
 * Exo session integration basing on
 * org.exoplatform.frameworks.jcr.web.SimpleSessionFactoryInitializedFilter.
 *
 * @author Andriy Zhdanov
 */
public class SessionIntegrationFilter implements Filter {
    private ServletContext servletContext;
    private static final String SESSIONFILTER_CALLED =
            "exogwt.server.web.SessionIntegrationFilter.filterCalled";

    public void init(FilterConfig filterConfig) throws ServletException {
        servletContext = filterConfig.getServletContext();
    }

    public void doFilter(ServletRequest servletRequest,
                         ServletResponse servletResponse,
                         FilterChain filterChain)
            throws IOException, ServletException {

        if (servletRequest.getAttribute(SESSIONFILTER_CALLED) != null) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }

        servletRequest.setAttribute(SESSIONFILTER_CALLED, "true");

        if (!(servletRequest instanceof HttpServletRequest)) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }

        HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
        HttpSession httpSession = httpRequest.getSession();

        SessionContainer sessionContainer = SessionContainer.getInstance();
        if (sessionContainer == null) {
            sessionContainer = Exo.getSessionContainer(httpSession.getId());
            if (sessionContainer == null) {
                // initialize sessionContainer
                // TODO: use rememberMe service
                ClientInfo clientInfo = (new ServiceClientInfo(null,
                        httpRequest.getRemoteAddr()));
                sessionContainer = Exo.createSessionContainer(httpSession.getId(),
                        clientInfo);
            }
            // attach to current thread
            SessionContainer.setInstance(sessionContainer);
        }

        filterChain.doFilter(servletRequest, servletResponse);
    }

    /**
     * {@inheritDoc}
     */
    public void destroy() {
        // nothing to do
    }
}
